#include "protocol_header.hh"

#include "../../corelib/network/thirdparty/knet/misc.h"

#ifdef WIN32
#include <WinSock2.h>
#pragma comment(lib, "wsock32.lib")
#else
#include <arpa/inet.h>
#endif

uint64_t _htonll(uint64_t ui64) {
    return (((uint64_t)htonl((uint32_t)ui64)) << 32) + htonl(ui64 >> 32);
}

uint64_t _ntohll(uint64_t ui64) {
    return (((uint64_t)ntohl((uint32_t)ui64)) << 32) + ntohl(ui64 >> 32);
}

void ProtocolHeader::hton() {
    msgID = htonl(msgID);
    length = htonl(length);
}

void ProtocolHeader::ntoh() {
    msgID = ntohl(msgID);
    length = ntohl(length);
}

ProtocolHeader::ProtocolHeader() {
    length = 0;
    msgID = 0;
}

ProtocolHeader::ProtocolHeader(const char * address) {
    length = *reinterpret_cast<const std::uint32_t*>(address);
    msgID = *reinterpret_cast<const std::uint32_t*>(address + sizeof(std::uint32_t));
    ntoh();
}

void ProtocolLocatorHeader::hton() {
    msgID = htonl(msgID);
    length = htonl(length);
    locatorMsgLength = htonl(locatorMsgLength);
}

void ProtocolLocatorHeader::ntoh() {
    msgID = ntohl(msgID);
    length = ntohl(length);
    locatorMsgLength = ntohl(locatorMsgLength);
}

ProtocolLocatorHeader::ProtocolLocatorHeader(const char * address) {
    length = *reinterpret_cast<const std::uint32_t*>(address);
    msgID = *reinterpret_cast<const std::uint32_t*>(address + sizeof(std::uint32_t));
    locatorMsgLength = *reinterpret_cast<const std::uint32_t*>(address + sizeof(std::uint32_t) * 2);
    ntoh();
}

ProtocolLocatorHeader::ProtocolLocatorHeader() {
    length = 0;
    msgID = 0;
    locatorMsgLength = 0;
}

void ProtocolLocatorHeader::toBuffer(char * address, std::uint32_t length, std::uint32_t msgID, std::uint32_t locatorMsgLength) {
    *reinterpret_cast<std::uint32_t*>(address) = htonl(length);
    *reinterpret_cast<std::uint32_t*>(address + sizeof(std::uint32_t)) = htonl(msgID);
    *reinterpret_cast<std::uint32_t*>(address + sizeof(std::uint32_t) * 2) = htonl(locatorMsgLength);
}
